﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.CounterManager;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.Preferences;
using ApplicationLibrary.RicherTextBox;
using ApplicationLibrary.SqlConnector;
using Plumber.Masters.ModuleData;
using Plumber.Sales.ModuleData;
using Plumber.Sales.Reports;
using Plumber.Sales.Reports.DataSet;

namespace Plumber.Sales.Forms
{
    public partial class Quotations : DocumentForm
    {
        private const string PRINT_INVOICE = "PRINT_INVOICE";
        private const string PRINT_INVOICE_LOGO = "PRINT_INVOICE_LOGO";
        private const string PRINT_INVOICE_NOLOGO = "PRINT_INVOICE_NOLOGO";
        private const string PRINT_ENVELOPE = "PRINT_ENVELOPE";
        private ComboBoxManager TemplateManager = null;
        private DRTemplatesByInvoice DRTemplatesByInvoice = null;
        private ListBoxManager<string> SentenceManager = null;
        private DRMasterType DRMasterType = null;
        private DRMasters DRMaster = null;
        private DSQuotation dSQuotation = null;
        private DRTemplates DRTemplates = null;
        private RRSentences RRSentence = null;
        private DRTitle DRTitle = null;
        private PreferencesManager<NHUnspellPref> myLanguage = null;
        private NHUnspellPref NHUnspellPref = null;
        private DRMasterTypeByType dRMasterTypeByType;
        private ComboBoxManager cbbManager;
        private CounterFormatter formatter = new CounterFormatter();

        private MasterTypes masterType = MasterTypes.E_Other;
        private string adminType = string.Empty;
        private string condomType = string.Empty;

        public Quotations()
            : base(Properties.Resources.FN_Quotations)
        {
            InitializeComponent();
            InitializeAuxComponent();

            ReadPreferences();
        }

        private void ReadPreferences()
        {
            myLanguage = new PreferencesManager<NHUnspellPref>(formName, null);
            NHUnspellPref = myLanguage.ReadPreference();
            if (NHUnspellPref.Enable)
                rtbBody.Language = NHUnspellPref.Language;
            else
                rtbBody.SpellingEnable = false;
        }

        private void InitializeAuxComponent()
        {
        }

        #region Virtual Method

        protected override IRadarParameters GetKeyFromDocument()
        {
            return new RadarSaleInvoicesParam(fncQuotationNo.Text);
        }

        protected override void OnAttachData()
        {
            dbManager = new dbmanagerQuotations("Quotations", new RadarQuotations(), this);
            dbManager.AddMaster(this, PL_Quotations.Name, true);

            dSQuotation = new DSQuotation();

            RRMasterTypeForInvoice rrMasterType = new RRMasterTypeForInvoice();
            rrMasterType.Find();

            cbbManager = new ComboBoxManager();
            for (int t = 0; t < rrMasterType.Count; t++)
                if (rrMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType, t) != MasterTypes.E_Administrator)
                    cbbManager.AddValue(rrMasterType.GetValue<string>(PL_MasterType.Code, t), rrMasterType.GetValue<string>(PL_MasterType.Description, t));
            cbbManager.AttachTo(cbbType);

            dRMasterTypeByType = new DRMasterTypeByType();

            if (dRMasterTypeByType.Find(MasterTypes.E_Condominium))
            {
                condomType = dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);
                rdrCode.AttachCodeType(condomType);
                rdrCode.RadarForm = new RadarMasterForm(condomType, RadarMasterForm.Module.Master);
                rdrCode.RadarForm.EnableAddOnFly = true;
                rdrCode.DescriptionControl = txtDescription;
                cbbType.SelectedValue = condomType;
            }

            if (dRMasterTypeByType.Find(MasterTypes.E_Administrator))
            {
                adminType = dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);
                rdrAdmin.AttachCodeType(adminType);
                rdrAdmin.RadarForm = new RadarMasterForm(adminType, RadarMasterForm.Module.Master);
                rdrAdmin.RadarForm.EnableAddOnFly = true;
                rdrAdmin.DescriptionControl = lblAdminDesc;
            }

            fncQuotationNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Quotations), GlobalInfo.CurrentDate, dbManager.Transaction);
            formatter.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Quotations), GlobalInfo.CurrentDate);

            rdrTitle.RadarForm = new RadarTitles();
            rdrTitle.DescriptionControl = lblTitleDesc;

            TemplateManager = new ComboBoxManager(cbbTemplates);
            DRTemplatesByInvoice = new DRTemplatesByInvoice(dbManager.DBConnection, false);
            DRTemplates = new DRTemplates(false);
            DRMaster = new DRMasters(false);
            DRTitle = new DRTitle(false);
            DRMasterType = new DRMasterType(DRMasterType.Module.All);

            SentenceManager = new ListBoxManager<string>();
            RRSentence = new RRSentences(false);
            RRSentence.Find();
            for (int t = 0; t < RRSentence.Count; t++)
                SentenceManager.AddValue(RRSentence.GetValue<string>(PL_Sentences.Text, t), RRSentence.GetValue<string>(PL_Sentences.Title, t));
            if (RRSentence.Count > 0)
                SentenceManager.AttachTo(lsbSentence);
        }

        protected override void OnBindData()
        {
            BindControl(fncQuotationNo, PL_Quotations.QuotationNo, "Text", Findable.YES);
            BindControl(ctbDate, PL_Quotations.ReleaseDate);
            BindControl(cbbType, PL_Quotations.Type, "SelectedValue", Findable.YES);
            BindControl(rdrCode, PL_Quotations.Master, Findable.YES);
            BindControl(txtDescription, PL_Quotations.Description);
            BindControl(txtAddress, PL_Quotations.Address);
            BindControl(txtCity, PL_Quotations.City);
            BindControl(mtbZip, PL_Quotations.ZipCode);
            BindControl(txtCounty, PL_Quotations.County);
            BindControl(mtbTaxNo, PL_Quotations.TaxNo);
            BindControl(mtbFiscalCode, PL_Quotations.FiscalCode);

            BindControl(rdrTitle, PL_Quotations.Title);

            BindControl(rdrAdmin, PL_Quotations.Administrator, Findable.YES);

            BindControl(rtbBody, PL_Quotations.QuotationBody, "Rtf");
            BindControl(txtNote, PL_Quotations.Note);

            BindControl(lsbSentence);
            BindControl(cbbTemplates);
            BindControl(btnLoad);

            BindCounter(fncQuotationNo);
        }

        protected override void OnPrepareAuxData()
        {
            rdrAdmin.UpdateDescription();
            rdrTitle.UpdateDescription();
            base.OnPrepareAuxData();
        }

        protected override bool OnBeforeSave()
        {
            CodeMode codeMode = CodeMode.E_CanBeEmpty;
            if (DRMasterType.Find(cbbManager.GetValue<string>()))
                codeMode = DRMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode);

            if (string.IsNullOrEmpty(rdrCode.Text) && codeMode == CodeMode.E_MustExists)
            {
                string mess = string.Format(Properties.Resources.Msg_MissingCode, DRMasterType.GetValue<string>(PL_MasterType.Description, 0));
                MyMessageBox(this, mess,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (rtbBody.Rtf.Length > 4000)
            {
                MyMessageBox(this, Properties.Resources.Msg_TextTooLenght,
                Properties.Resources.Error,
                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return base.OnBeforeSave();
        }

        protected override bool OnAfterAddNew()
        {
            cbbType.SelectedValue = condomType;
            return true;
        }

        protected override void FocusOnNew()
        {
            fncQuotationNo.Focus();
        }

        protected override void OnDisableControlsForEdit()
        {
            fncQuotationNo.Enabled = false;
            rdrAdmin.Enabled = DRMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType) == MasterTypes.E_Condominium;
            btnLoad.Enabled = TemplateManager.Count<string>() > 0;
            cbbTemplates.Enabled = TemplateManager.Count<string>() > 1;
        }

        protected override void OnDisableControlsForNew()
        {
            btnLoad.Enabled = TemplateManager.Count<string>() > 0;
            cbbTemplates.Enabled = TemplateManager.Count<string>() > 1;
            ctbDate.Today = GlobalInfo.CurrentDate;
            cbbType_SelectedIndexChanged(this, EventArgs.Empty);
            base.OnDisableControlsForNew();
        }

        #endregion

        private void cbbType_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DRMasterType == null || cbbManager.GetValue<string>() == default(string))
                return;

            CodeMode codeMode = CodeMode.E_MustExists;

            if (DRMasterType.Find(cbbManager.GetValue<string>()))
            {
                codeMode = DRMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode);
                masterType = DRMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType);
            }

            if (codeMode == CodeMode.E_IsEmpty)
            {
                rdrCode.Enabled = false;
                rdrCode.DeattachAll();
            }
            else
            {
                rdrCode.ReattachCodeType(cbbManager.GetValue<string>());
                rdrCode.Enabled = true;
                rdrCode.RadarForm.FilterType = cbbManager.GetValue<string>();
            }

            rdrAdmin.Visible = lblAdminDesc.Visible = DRMasterType.GetValue<MasterTypes>(PL_MasterType.MasterType) == MasterTypes.E_Condominium;
            TemplateFiller();
        }

        private void TemplateFiller()
        {
            if (TemplateManager == null)
                return;

            TemplateManager.Clear<string>();
            if (DRTemplatesByInvoice.Find(TemplateType.E_Quotation, cbbManager.GetValue<string>()))
            {
                for (int t = 0; t < DRTemplatesByInvoice.Count; t++)
                {
                    string code = DRTemplatesByInvoice.GetValue<string>(PL_Templates.Code, t);
                    string desc = DRTemplatesByInvoice.GetValue<string>(PL_Templates.Description, t);

                    TemplateManager.AddValue(code, desc);
                }
            }
            TemplateManager.Refresh();

            if (IsNew && TemplateManager.Count<string>() == 1)
                LoadTemplate();

            btnLoad.Enabled = TemplateManager.Count<string>() > 0;
            cbbTemplates.Enabled = TemplateManager.Count<string>() > 1;
        }

        private void LoadTemplate()
        {
            if (DRTemplates.Find(TemplateType.E_Quotation, TemplateManager.GetValue<string>()))
                rtbBody.Rtf = DRTemplates.GetValue<string>(PL_Templates.Body);
        }

        private void rdrCode_Validating(object sender, CancelEventArgs e)
        {
            if (string.IsNullOrEmpty(cbbManager.GetValue<string>()) || rdrCode.IsEmpty)
                return;

            if (DRMaster.Find(cbbManager.GetValue<string>(), rdrCode.Text))
                LoadDataInInvoice();
        }

        private void LoadDataInInvoice()
        {
            txtAddress.Text = DRMaster.GetValue<string>(PL_Masters.Address);
            txtCity.Text = DRMaster.GetValue<string>(PL_Masters.City);
            txtCounty.Text = DRMaster.GetValue<string>(PL_Masters.County);
            mtbZip.Text = DRMaster.GetValue<string>(PL_Masters.ZipCode);
            mtbTaxNo.Text = DRMaster.GetValue<string>(PL_Masters.TaxNo);
            mtbFiscalCode.Text = DRMaster.GetValue<string>(PL_Masters.FiscalCode);
            rdrAdmin.Text = DRMaster.GetValue<string>(PL_Masters.Administrator);
            rdrTitle.Text = DRMaster.GetValue<string>(PL_Masters.Title);

            rdrAdmin.UpdateDescription();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            bool bBodyFill = rtbBody.Text != string.Empty;

            if (!bBodyFill || bBodyFill && MyMessageBox(this, Properties.Resources.Msg_BodyNotEmpty,
            Properties.Resources.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Hand) == System.Windows.Forms.DialogResult.Yes)
                LoadTemplate();
        }

        private void lsbSentence_MouseMove(object sender, MouseEventArgs e)
        {
            int idx = lsbSentence.IndexFromPoint(e.X, e.Y);
            if (idx >= 0 && tltSentence.GetToolTip(lsbSentence) != lsbSentence.Items[idx].ToString())
                tltSentence.SetToolTip(lsbSentence, lsbSentence.Items[idx].ToString());
        }

        private void lsbSentence_MouseDown(object sender, MouseEventArgs e)
        {
            int idx = lsbSentence.IndexFromPoint(e.X, e.Y);
            if (e.Button != MouseButtons.Left)
                idx = -1; ;

            if (idx >= 0)
                DoDragDrop(new DataObject(DataFormats.Rtf, lsbSentence.Items[idx].ToString()), DragDropEffects.Copy);
        }

        private void rtbBody_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.Rtf)
                             ? DragDropEffects.Copy
                             : DragDropEffects.None;
        }

        private void rtbBody_RicherDragOver(object sender, DragEventArgs e)
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.Rtf)
                 ? DragDropEffects.Copy
                 : DragDropEffects.None;
        }

        private int GetCaretIndexFromPoint(RicherTextBox tb, int x, int y)
        {
            Point p = tb.PointToClient(new Point(x, y));
            int i = tb.TextBox.GetCharIndexFromPosition(p);
            if (i == tb.Text.Length - 1)
            {
                Point c = tb.TextBox.GetPositionFromCharIndex(i);
                if (p.X > c.X)
                    i++;
            }
            return i;
        }

        private bool SalesInvoice_OnEnableToolbarSplitButtons(ToolStripSplitButton sender)
        {
            return true;
        }

        protected override void OnAddSplitMenuButton()
        {
            AddSplitPreviewButton(Properties.Resources.PRNT_QUOTATION, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_QUOTATION_LOGO, PRINT_INVOICE_LOGO, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_QUOTATION_NOLOGO, PRINT_INVOICE_NOLOGO, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Envelope, Properties.Resources.B_Envelope);

            AddSplitPrintButton(Properties.Resources.PRNT_QUOTATION, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_QUOTATION_LOGO, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_QUOTATION_NOLOGO, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Envelope, Properties.Resources.B_Envelope);
        }

        protected override bool OnPrintDocument(PrintInfo sender, printerForm pf)
        {
            pf.SendEmail += new printerForm.EmailArgsEventHanlder(pf_SendEmail);
            pf.LoadAddress += new printerForm.LoadAddressEventHandler(pf_LoadAddress);
            switch (sender.ReportName)
            {
                case PRINT_INVOICE:
                    return PrintQuotation(pf,true);
                case PRINT_INVOICE_NOLOGO:
                    return PrintQuotation(pf, true);
                case PRINT_INVOICE_LOGO:
                    return PrintQuotation(pf, false);
                case PRINT_ENVELOPE:
                    return PrintEnvelope(pf);
                default:
                    return true;
            }
        }

        private void pf_LoadAddress(ApplicationLibrary.Emailer.emailAddress ea)
        {
            Plumber.Masters.Library.EmailAddressLoader emailLoader = new Masters.Library.EmailAddressLoader();
            emailLoader.LoadAddress(ea);
        }

        private void pf_SendEmail(object sender, EmailArgs e)
        {
            printerForm pf = (printerForm)sender;
            pf.ChangeParameterValue("HideLogo", false);
            e.Attachment = pf.ExportToPdf(fncQuotationNo.Text);
            e.Address = GetAddress();
            e.Subject = string.Format(Properties.Resources.Msg_EmittedQuotation, formatter.ToString(true), ctbDate.Today.ToShortDateString());
        }

        private string GetAddress()
        {
            if (cbbType.SelectedValue.ToString() == condomType)
                DRMaster.Find(adminType, rdrCode.Text);
            else
                DRMaster.Find(cbbType.SelectedValue.ToString(), rdrCode.Text);

            return DRMaster.GetValue<string>(PL_Masters.Email);
        }

        private bool PrintQuotation(printerForm pf, bool hidelogo = true)
        {
            dSQuotation.Quotation.Clear();

            DSQuotation.QuotationRow row = dSQuotation.Quotation.NewQuotationRow();

            pf.Text = Properties.Resources.CN_Quotations;

            formatter.Text = fncQuotationNo.Text;
            row[PL_Quotations.QuotationNo.Name] = formatter.ToString(true);

            string desc = lblTitleDesc.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' });
            desc = desc.SeparConcat(txtDescription.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' }), "\n");
            desc = desc.SeparConcat(txtAddress.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' }), "\n");

            row[PL_Quotations.Description.Name] = string.Concat(desc, "\n", mtbZip.Text, " ", txtCity.Text, " ", txtCounty.Text);
            row[PL_Quotations.ReleaseDate.Name] = ctbDate.Today;
            row[PL_Quotations.QuotationBody.Name] = rtbBody.Rtf;

            dSQuotation.Quotation.AddQuotationRow(row);

            pf.SetParameterValue("HideLogo", hidelogo);
            pf.ShowReport(new PrintQuotation(), dSQuotation);
            return true;
        }

        private bool PrintEnvelope(printerForm pf)
        {
            Plumber.Masters.Library.PrintEnvelope printEnvelope = new Plumber.Masters.Library.PrintEnvelope(pf);

            if (masterType == MasterTypes.E_Condominium && !string.IsNullOrEmpty(rdrAdmin.Text))
            {
                if (DRMaster.Find(adminType, rdrAdmin.Text))
                {
                    string titleText = "";
                    if (DRTitle.Find(DRMaster.GetValue<string>(PL_Masters.Title)))
                        titleText = DRTitle.GetValue<string>(PL_Titles.Description);

                    printEnvelope.Print(titleText,
                                        DRMaster.GetValue<string>(PL_Masters.Description),
                                        DRMaster.GetValue<string>(PL_Masters.Address),
                                        DRMaster.GetValue<string>(PL_Masters.ZipCode),
                                        DRMaster.GetValue<string>(PL_Masters.City),
                                        DRMaster.GetValue<string>(PL_Masters.County));
                }
            }
            else
                printEnvelope.Print(lblTitleDesc.Text, txtDescription.Text, txtAddress.Text, mtbZip.Text, txtCity.Text, txtCounty.Text);

            return true;
        }
    }

    #region DbManager SalesInvoice

    /// <summary>
    /// Classe derivata per gestioni particolari
    /// </summary>
    ///

    internal class dbmanagerQuotations : DBManager
    {
        private const string JESlave = "JESLAVE";

        public dbmanagerQuotations(string name, RadarForm radar, DocumentForm document)
            : base(name, radar, document)
        { }

        protected override string CreateMasterQuery()
        {
            this.Table = new PL_Quotations();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(this.Table);
            qB.AddCompare(PL_Quotations.QuotationNo, "@p1");

            return qB.Query;
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();

            SqlABParameter sParam = new SqlABParameter("@p1", PL_Quotations.QuotationNo);
            sParam.Value = 0;
            PList.Add(sParam);
            return PList;
        }

        protected override void SetParameters(IRadarParameters key, DBCollection collection)
        {
            if (collection.Name == PL_Quotations.Name)
            {
                collection.Parameter[0].Value = key[0];
            }
        }
    }

    #endregion
}